/**
 * Copyright
 *
 * All rights reserved
 *
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under this License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations.
 *
 * This file originally written by Chetan Padhye
 *
 */
var width = 960;
var height = 650;
var force, link, node, linkedByIndex = {};
var tooltip = Tooltip("vis-tooltip", 300);

var svg = d3.select("#grapharea")
    .append("svg:svg")
    .attr("width", width)
    .attr("height", height)
    .attr("pointer-events", "all")
    .append('svg:g')
    .call(d3.behavior.zoom().on("zoom", redraw))
    .append('svg:g');
svg.append('svg:rect')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', '#FFF');
    //.attr('fill', '#4D525A');


var node_drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);


function update() {
    force.stop();
    link.remove();
    node.remove();
    return force.start();
};

function redraw() {
    svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}

function draw(json) {
    force = d3.layout.force()
        .charge(-700)
        .linkDistance(450)
        .size([width, height])
        .gravity(2);
    force.nodes(json.nodes).links(json.links).start();
    link = svg.selectAll(".link")
        .data(json.links)
        .enter().append("line")
        .attr("class", function (l) {
            return l.classname;
        });
    link.on("click", showDetails).on("mouseout", hideDetails);
    node = svg.selectAll(".node")
        .data(json.nodes)
        .enter().append("g")
        .attr("class", "node")
        .call(node_drag);
    node.append("image")
        .attr("xlink:href", function (d) {
            return "img/" + d.icon;
        })
        .attr("x", function (d) {
        	return  - (d.icon.split('_')[3] / 2);
        })
        .attr("y",  function (d) {
        	return  - (d.icon.split('_')[3] / 2);
        })
        .attr("width", function (d) {
        	return d.icon.split('_')[3];
        })
        .attr("height", function (d) {
        	return d.icon.split('_')[3];
        });
    node.append("text")
	    .attr("fill", "#000")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .text(function (d) {
            return d.name;
        });
    node.on("click", showDetails).on("mouseout", hideDetails);
    force.on("tick", tick);
    
    
   
};
function tick(){
    link.attr("x1", function (d) {
        return d.source.x;
    })
        .attr("y1", function (d) {
            return d.source.y;
        })
        .attr("x2", function (d) {
            return d.target.x;
        })
        .attr("y2", function (d) {
            return d.target.y;
        });
    node.attr("transform", function (d) {
        return "translate(" + d.x + "," + d.y + ")";
    });
}
function showDetails(d, i) {
    if (d.name !== undefined) {
        // Node
        content = '<p class="main"><span class="left">' + d.name + '</span></p>';
    } else {
        //link
        content = '<p class="main"><span class="left">' + 'Relationship Edge' + '</span></p>';
    }
    content += '<hr class="tooltip-hr">';
    content += '<div class="tipcontent">';
    $.each(d, function (k, v) {
        // display the key and value pair
        if ($.inArray(k, ['Name','name', 'Company', 'Location', 'Job Title','Job Level','Political Power', 'Department', 'FoT', 'Relationship Strength', 'Start Date']) != -1) {
            content += '<p class="caps"><span class="bold">' + k + ':</span><span>  ' + v + ' </span></p>';
        }
    });
    content += '</div>';
    tooltip.showTooltip(content, d3.event);
	if (d.name !== undefined) {   
	    if (link) {
			link.attr("class", function(l) {
				if (l.source === d || l.target === d) {
					return "highlight";
				} else {
					return l.classname;
				}
			});
		}
	} 
}

neighboring = function(a, b) {
	return linkedByIndex[a.id + "," + b.id]
			|| linkedByIndex[b.id + "," + a.id];
};

function hideDetails(d, i) {
    tooltip.hideTooltip()
}

function setupData(data) {
    var  nodesMap;
    nodesMap = mapNodes(data.nodes);
    data.links.forEach(function (l) {
        l.source = nodesMap.get(l.source);
        l.target = nodesMap.get(l.target);
        return linkedByIndex["" + l.source.id + "," + l.target.id] = 1;
    });
    return data;
};

function mapNodes(nodes) {
    var nodesMap;
    nodesMap = d3.map();
    nodes.forEach(function (n) {
        return nodesMap.set(n.id, n);
    });
    return nodesMap;
};


function dragstart(d, i) {
    force.stop(); // stops the force auto positioning before you start dragging
}

function dragmove(d, i) {
    d.px += d3.event.dx;
    d.py += d3.event.dy;
    d.x += d3.event.dx;
    d.y += d3.event.dy; 
    tick(); // this is the key to make it work together with updating both px,py,x,y on d !
}

function dragend(d, i) {
    d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
    tick();
    force.resume();
}


function filterContact(json, joblevel, relstrength) {
    var nodeArr = [];
    json.nodes = jQuery.grep(json.nodes, function (element, index) {
        if (element["Job Level"] === joblevel) {
            nodeArr.push(element.id);
            return true;
        }
        return false;
    });
    json.links = jQuery.grep(json.links, function (element, index) {
        if ($.inArray(element.source, nodeArr) != -1 && $.inArray(element.target, nodeArr) != -1) {
            return true;
        }
        return false;
    });
}

function filterEdges(json, joblevel, relstrength) {
    var nodeArr = [];
    json.links = jQuery.grep(json.links, function (element, index) {
        if (element["Relationship Strength"] === relstrength) {
            nodeArr.push(element['source']);
            nodeArr.push(element['target']);
            return true;
        }
        return false;
    });
    json.nodes = jQuery.grep(json.nodes, function (element, index) {
        if ($.inArray(element.id, nodeArr) != -1) {
            return true;
        }
        return false;
    });
}

function filterContactByCompany(json, company) {
    var nodeArr = [];
    json.nodes = jQuery.grep(json.nodes, function (element, index) {
        if (element["Company"] === company) {
            nodeArr.push(element.id);
            return true;
        }
        return false;
    });
    json.links = jQuery.grep(json.links, function (element, index) {
        if ($.inArray(element.source, nodeArr) != -1 && $.inArray(element.target, nodeArr) != -1) {
            return true;
        }
        return false;
    });
}


function filter(json) {
    var joblevel = $('#joblevel').val();
    var relstrength = $('#relstrength').val();
    var company = $('#company').val();
    if(company!== 'select') {
	   filterContactByCompany(json,company);
    }
	   
    if (joblevel !== 'select' && relstrength !== 'select') {
        filterContact(json, joblevel, relstrength);
        filterEdges(json, joblevel, relstrength);
    } else if (joblevel !== 'select') {
        filterContact(json, joblevel, relstrength);
    } else if (relstrength !== 'select') {
        filterEdges(json, joblevel, relstrength);
    } else if (joblevel === 'select' && relstrength === 'select') {
        // json unmodified. Do nothing.
    }
}
// Dom ready Function
$(function () {
    $('#showgraph').click(function () {
        d3.json('./data/connections.json', function (json) {
            update();
            filter(json);
            draw(setupData(json));
        });
    });
    d3.json('./data/connections.json', function (json) {
        draw(setupData(json));
    });
});